﻿/*
 *  Author: Louis A. Leskoviansky
 *  Company: Artemis Solutions Group (http://www.artemis-solutions.com)
 */


using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;

namespace AjaxControlFramework
{
    public static class TypeCache
    {
        //------// Properties \\--------------------------------------------\\
        private delegate object ObjectConstructor();

        private static Dictionary<string, ObjectConstructor> _internalCollection = new Dictionary<string, ObjectConstructor>();
        //------\\ Properties //--------------------------------------------//



        //------// Methods \\-----------------------------------------------\\
        public static T CreateObject<T>() where T : new()
        {
            return (T)CreateObject(typeof(T));
        }


        public static object CreateObject(Type objectType)
        {
            if (objectType == null) { return null; }

            if (_internalCollection.ContainsKey(objectType.FullName))
            {
                return _internalCollection[objectType.FullName]();
            }
            else
            {
                ObjectConstructor createObjectMethod = null;

                ConstructorInfo controlConstructor = objectType.GetConstructor(Type.EmptyTypes);
                DynamicMethod dynamicMethod = new DynamicMethod(objectType.Name, objectType, Type.EmptyTypes);

                ILGenerator ilGenerator = dynamicMethod.GetILGenerator();
                ilGenerator.Emit(OpCodes.Newobj, controlConstructor);
                ilGenerator.Emit(OpCodes.Ret);

                createObjectMethod = (ObjectConstructor)dynamicMethod.CreateDelegate(typeof(ObjectConstructor));
                _internalCollection[objectType.FullName] = createObjectMethod;

                return createObjectMethod();
            }
        }
        //------\\ Methods //-----------------------------------------------//
    }
}
